/*
 * @Description: grpc server entry.
 * @Version: V1.0
 * @Author: zw_1520@163.com
 * @Date: 2024-09-02 08:42:26
 * @LastEditors: zw_1520@163.com
 * @LastEditTime: 2025-07-02 11:24:15
 * Copyright (C) All rights reserved.
 */

#include "robot_grpc_communicator.h"

#include <jsoncpp/json/json.h>
#include <rclcpp/rclcpp.hpp>

class GrpcClient : public rclcpp::Node {
public:
  GrpcClient() : Node("robot_grpc_client") {
    client_ = new RobotGrpcClient(grpc::CreateChannel(
        "10.15.228.3:50051", grpc::InsecureChannelCredentials()));
    RCLCPP_INFO(this->get_logger(), "Starting robot grpc client...");
    clientLogin();

    RCLCPP_INFO(this->get_logger(), "Robot grpc client login success.");

    // Sleeps for 100ms
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
    startMedia();
    RCLCPP_INFO(this->get_logger(), "Robot grpc client start media success.");
    return;
  }

public:
  bool clientLogin() {
    // Construct the message
    GeneralMsg msg;
    // string id = 2;
    // string sid = 3;
    // string type = 4;
    // string seq = 5;
    // string guid = 6;
    // string ver = 7;
    // string from = 8;
    // string to = 9;
    // string src = 10;
    // string dest = 11;
    // string root_guid = 12;
    // int64 deadline = 13;        // MilliSecond
    // string robot_id = 14;

    msg.set_id("login");
    msg.set_sid("");
    msg.set_type("login");
    msg.set_seq("1");
    msg.set_guid("efbcfd60-56f2-11f0-96d3-63f4f70700e3");
    msg.set_ver("1.0.0");
    msg.set_from("robot_007");
    msg.set_to("cloud");
    msg.set_src("robot_007");
    msg.set_dest("cloud");
    msg.set_root_guid("efbcfd60-56f2-11f0-96d3-63f4f70700e3");
    msg.set_deadline(5000);
    msg.set_robot_id("GINLITXR-1LXXXXXXXXXGNL03S2113000026");

    // Constructs robot login message
    Login login;
    login.set_account_id("GL0026");
    login.set_password("password123");
    login.set_tenant_id("86gingerlite");
    login.set_device_id("GINLITXR-1LXXXXXXXXXGNL03S2113000026");
    login.set_robot_id("GINLITXR-1LXXXXXXXXXGNL03S2113000026");
    login.set_app_type("reception");
    login.set_lang("CH");
    login.set_device_first_connection(true);
    login.set_device_first_connection_date(
        std::chrono::duration_cast<std::chrono::milliseconds>(
            std::chrono::system_clock::now().time_since_epoch())
            .count());
    login.set_main_camera("front");
    login.set_need_init_result(false);

    // Creates any object to pack
    google::protobuf::Any any;
    any.PackFrom(login);

    // Checks that the message is packed
    if (any.Is<Login>()) {
      std::cout << "Any contains Login message" << std::endl;

      // Unpacks the message and check
      Login unpacked_login;
      if (any.UnpackTo(&unpacked_login)) {
        std::cout << "Unpacked account_id: " << unpacked_login.account_id()
                  << std::endl;
      }
    }
    msg.mutable_params()->PackFrom(login);

    // Sends the message
    client_->sendData(msg);
    return true;
  }

  bool startMedia() {
    // Construct the message
    GeneralMsg msg;
    // string id = 2;
    // string sid = 3;
    // string type = 4;
    // string seq = 5;
    // string guid = 6;
    // string ver = 7;
    // string from = 8;
    // string to = 9;
    // string src = 10;
    // string dest = 11;
    // string root_guid = 12;
    // int64 deadline = 13;        // MilliSecond
    // string robot_id = 14;

    msg.set_id("login");
    msg.set_sid("");
    msg.set_type("login");
    msg.set_seq("1");
    msg.set_guid("efbcfd60-56f2-11f0-96d3-63f4f70700e3");
    msg.set_ver("1.0.0");
    msg.set_from("robot_007");
    msg.set_to("cloud");
    msg.set_src("robot_007");
    msg.set_dest("cloud");
    msg.set_root_guid("efbcfd60-56f2-11f0-96d3-63f4f70700e3");
    msg.set_deadline(5000);
    msg.set_robot_id("GINLITXR-1LXXXXXXXXXGNL03S2113000026");

    // Constructs start media message
    // 1. 构建SDP offer(示例内容参考RFC8866规范)
    std::string sdp_offer =
        "v=0\r\no=- 0 0 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n"
        "m=audio 9 UDP/TLS/RTP/SAVPF 111\r\na=rtpmap:111 OPUS/48000/2";

    // 2. 填充StartMedia消息
    StartMedia start_media_request;
    start_media_request.set_sdp_offer(sdp_offer);
    start_media_request.set_urgent(1); // 紧急级别
    start_media_request.set_destroy_media(false);
    start_media_request.set_mode("push");     // 传输模式
    start_media_request.set_webrtc_asr(true); // 启用语音识别

    // Creates any object to pack
    google::protobuf::Any any;
    any.PackFrom(start_media_request);

    // Checks that the message is packed
    if (any.Is<StartMedia>()) {
      std::cout << "Any contains StartMedia message" << std::endl;

      // Unpacks the message and check
      StartMedia unpacked_start_media;
      if (any.UnpackTo(&unpacked_start_media)) {
        std::cout << "Unpacked sdp_offer: " << unpacked_start_media.sdp_offer()
                  << std::endl;
      }
    }
    msg.mutable_params()->PackFrom(start_media_request);

    // Sends the message
    client_->sendData(msg);
    return true;
  }

private:
  RobotGrpcClient *client_;
};

int main(int argc, char **argv) {
  //  Inits node
  rclcpp::init(argc, argv);
  rclcpp::Node::SharedPtr robot_grpc_client_node =
      std::make_shared<GrpcClient>();

  // Starts executor
  auto executor = std::make_shared<rclcpp::executors::MultiThreadedExecutor>();
  executor->add_node(robot_grpc_client_node);
  executor->spin();

  // Stops node
  rclcpp::shutdown();
  return 0;
}